{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Teleportation example showcasing IF_M blocks\n",
    "This notebook uses Qubiter to illustrate quantum Teleportation \n",
    "of the pure state of one qubit (at 0) to another qubit (at 2) with the help of an ancilla qubit (at 1).\n",
    "\n",
    "The purpose of this notebook is not to teach about the \"theory\" behind quantum Teleportation.\n",
    "For that, the reader can go to numerous sources on the internet (Wikipedia, course notes, etc.)\n",
    "The purpose is to showcase some of the features of Qubiter, especially IF_M blocks (and also PRINT statements and calculations and plotting of various density matrices associated with any quantum circuit).\n",
    "\n",
    "For a full inventory of Qubiter English file commands, see <a href=\"../qubiter_rosetta_stone.pdf\">\n",
    "Qubiter's Rosetta Stone pdf</a>\n",
    "\n",
    "IBM has posted at https://github.com/QISKit/qiskit-tutorial, a jupyter notebook similar to this one, analysing the same quantum circuit for quantum Teleportation from one qubit to another. Their notebook uses IBM's qasm language instead of Qubiter's language so you might profit from comparing their notebook to this one to decide which qc language you prefer. Qubiter includes subroutines that can translate its language to IBM qasm that can then be run on IBM qc hardware.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First change your working directory to the qubiter directory in your computer, and add its path to the path environment variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/jupyter_notebooks\n",
      "/home/rrtucci/PycharmProjects/qubiter\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "print(os.getcwd())\n",
    "os.chdir('../../')\n",
    "print(os.getcwd())\n",
    "sys.path.insert(0,os.getcwd())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next do imports:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loaded OneQubitGate, WITHOUT autograd.numpy\n"
     ]
    }
   ],
   "source": [
    "from qubiter.SEO_writer import *\n",
    "from qubiter.SEO_simulator import *\n",
    "from qubiter.StateVec import *\n",
    "from qubiter.Plotter import *\n",
    "import numpy as np\n",
    "# np.set_printoptions(precision=5)\n",
    "import pandas as pan\n",
    "import seaborn as sea; sea.set()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Number of qubits is 3.\n",
    "Note that we use \"bit\" for both qbits and cbits.\n",
    "Use a trivial circuit embedder that embeds 3 qubits into same 3 qubits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_qbits = 3\n",
    "emb = CktEmbedder(num_qbits, num_qbits)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Open a writer, and tell it where to write to.\n",
    "We will use zero bit last (ZL) convention which is the default."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "file_prefix = 'teleportation-with-ifs'\n",
    "wr = SEO_writer(file_prefix, emb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Write English and Picture files of the quantum circuit. Close those files once finished writing to them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_Rn(0, list(np.pi/180*np.array([20, 68, 46])))\n",
    "wr.write_PRINT(\"ALL\")\n",
    "\n",
    "wr.write_H(1)\n",
    "wr.write_cnot(control_bit=1, target_bit=2)\n",
    "#wr.write_one_qbit_gate(0, OneQubitGate.rot_ax, [-np.pi/8, 2])\n",
    "wr.write_cnot(control_bit=0, target_bit=1)\n",
    "wr.write_H(0)\n",
    "wr.write_PRINT(\"ALL\")\n",
    "\n",
    "wr.write_MEAS(0, kind=2)\n",
    "wr.write_MEAS(1, kind=2)\n",
    "\n",
    "wr.write_PRINT(\"ALL\")\n",
    "wr.write_IF_M_beg(Controls.new_single_trol(num_qbits, 0, True))\n",
    "wr.write_Z(2)\n",
    "wr.write_IF_M_end()\n",
    "wr.write_PRINT(\"ALL\")\n",
    "wr.write_IF_M_beg(Controls.new_single_trol(num_qbits, 1, True))\n",
    "wr.write_X(2)\n",
    "wr.write_IF_M_end()\n",
    "wr.write_PRINT(\"ALL\")\n",
    "    \n",
    "wr.close_files()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The English and Picture files just produced have been stored in the io_folder. Here are links to them:\n",
    "* <a href=\"../io_folder/teleportation-with-ifs_3_eng.txt\">../io_folder/teleportation-with-ifs_3_eng.txt</a>\n",
    "* <a href=\"../io_folder/teleportation-with-ifs_3_ZLpic.txt\">../io_folder/teleportation-with-ifs_3_ZLpic.txt</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's print the English file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>ROTN\t20.000000\t68.000000\t46.000000\tAT\t0</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>3</td><td style='text-align:left;'><pre>HAD2\tAT\t1</pre></td></tr><td style='border-right:1px solid red;'>4</td><td style='text-align:left;'><pre>SIGX\tAT\t2\tIF\t1T</pre></td></tr><td style='border-right:1px solid red;'>5</td><td style='text-align:left;'><pre>SIGX\tAT\t1\tIF\t0T</pre></td></tr><td style='border-right:1px solid red;'>6</td><td style='text-align:left;'><pre>HAD2\tAT\t0</pre></td></tr><td style='border-right:1px solid red;'>7</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>8</td><td style='text-align:left;'><pre>MEAS\t2\tAT\t0</pre></td></tr><td style='border-right:1px solid red;'>9</td><td style='text-align:left;'><pre>MEAS\t2\tAT\t1</pre></td></tr><td style='border-right:1px solid red;'>10</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>11</td><td style='text-align:left;'><pre>IF_M(\t0T\t){</pre></td></tr><td style='border-right:1px solid red;'>12</td><td style='text-align:left;'><pre>SIGZ\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>13</td><td style='text-align:left;'><pre>}IF_M</pre></td></tr><td style='border-right:1px solid red;'>14</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>15</td><td style='text-align:left;'><pre>IF_M(\t1T\t){</pre></td></tr><td style='border-right:1px solid red;'>16</td><td style='text-align:left;'><pre>SIGX\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>17</td><td style='text-align:left;'><pre>}IF_M</pre></td></tr><td style='border-right:1px solid red;'>18</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_eng_file(jup=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's print the Picture file. \n",
    "\n",
    "Time points downward, and, since we are using the ZL convention, the 0th qubit is rightmost. \n",
    "\n",
    "Note that after an M measurement, vertical lines \"|\"\n",
    "directly under M are replaced by colons \":\"\n",
    "\n",
    "Line n of English file corresponds to line n of Picture file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>|   |   R</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>3</td><td style='text-align:left;'><pre>|   H   |</pre></td></tr><td style='border-right:1px solid red;'>4</td><td style='text-align:left;'><pre>X---@   |</pre></td></tr><td style='border-right:1px solid red;'>5</td><td style='text-align:left;'><pre>|   X---@</pre></td></tr><td style='border-right:1px solid red;'>6</td><td style='text-align:left;'><pre>|   |   H</pre></td></tr><td style='border-right:1px solid red;'>7</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>8</td><td style='text-align:left;'><pre>|   |   M</pre></td></tr><td style='border-right:1px solid red;'>9</td><td style='text-align:left;'><pre>|   M   :</pre></td></tr><td style='border-right:1px solid red;'>10</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>11</td><td style='text-align:left;'><pre>IF_M(\t0T\t){</pre></td></tr><td style='border-right:1px solid red;'>12</td><td style='text-align:left;'><pre>Z   :   :</pre></td></tr><td style='border-right:1px solid red;'>13</td><td style='text-align:left;'><pre>}IF_M</pre></td></tr><td style='border-right:1px solid red;'>14</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>15</td><td style='text-align:left;'><pre>IF_M(\t1T\t){</pre></td></tr><td style='border-right:1px solid red;'>16</td><td style='text-align:left;'><pre>X   :   :</pre></td></tr><td style='border-right:1px solid red;'>17</td><td style='text-align:left;'><pre>}IF_M</pre></td></tr><td style='border-right:1px solid red;'>18</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_pic_file(jup=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we create a simulator object with the ground state (|0> for each qubit) as initial state.\n",
    "Creating the simulator automatically evolves the state from initial to final.\n",
    "\n",
    "The PRINT statements that we have inserted in the quantum circuit print to\n",
    "screen the state of the circuit at the line where they appear in the English and Picture files.\n",
    "Each PRINT is identified by its line number (line numbers start with 1, what is called 1 based numbers) in the Eng and Pic files."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "*************************beginning PRINT output\n",
      "PRINT line number=2\n",
      "*********branch= pure\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(000)ZL ( 0.095871 + 0.541881j)\t prob=0.302826\n",
      "(001)ZL (-0.801041 + 0.235600j)\t prob=0.697174\n",
      "total probability of state vector (=one if no measurements)= 1.000000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.302826, 0.697174), 1: (1.0, -0.0), 2: (1.0, -0.0)}\n",
      "****************************ending PRINT output\n",
      "\n",
      "*************************beginning PRINT output\n",
      "PRINT line number=7\n",
      "*********branch= pure\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(000)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(100)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "(010)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "(110)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(001)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(101)ZL ( 0.400520 - 0.117800j)\t prob=0.174294\n",
      "(011)ZL ( 0.400520 - 0.117800j)\t prob=0.174294\n",
      "(111)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "total probability of state vector (=one if no measurements)= 1.000000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.5, 0.5), 1: (0.5, 0.5), 2: (0.5, 0.5)}\n",
      "****************************ending PRINT output\n",
      "\n",
      "*************************beginning PRINT output\n",
      "PRINT line number=10\n",
      "*********branch= 0T1T\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(011)ZL ( 0.400520 - 0.117800j)\t prob=0.174294\n",
      "(111)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (0.0, 1.0), 2: (0.697174, 0.302826)}\n",
      "*********branch= 0T1F\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(001)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(101)ZL ( 0.400520 - 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (1.0, 0.0), 2: (0.302826, 0.697174)}\n",
      "*********branch= 0F1T\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(010)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "(110)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (1.0, 0.0), 1: (0.0, 1.0), 2: (0.697174, 0.302826)}\n",
      "*********branch= 0F1F\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(000)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(100)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (1.0, 0.0), 1: (1.0, 0.0), 2: (0.302826, 0.697174)}\n",
      "****************************ending PRINT output\n",
      "\n",
      "*************************beginning PRINT output\n",
      "PRINT line number=14\n",
      "*********branch= 0T1T\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(011)ZL ( 0.400520 - 0.117800j)\t prob=0.174294\n",
      "(111)ZL (-0.047936 - 0.270940j)\t prob=0.075706\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (0.0, 1.0), 2: (0.697174, 0.302826)}\n",
      "*********branch= 0T1F\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(001)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(101)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (1.0, 0.0), 2: (0.302826, 0.697174)}\n",
      "*********branch= 0F1T\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(010)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "(110)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (1.0, 0.0), 1: (0.0, 1.0), 2: (0.697174, 0.302826)}\n",
      "*********branch= 0F1F\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(000)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(100)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (1.0, 0.0), 1: (1.0, 0.0), 2: (0.302826, 0.697174)}\n",
      "****************************ending PRINT output\n",
      "\n",
      "*************************beginning PRINT output\n",
      "PRINT line number=18\n",
      "*********branch= 0T1T\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(011)ZL (-0.047936 - 0.270940j)\t prob=0.075706\n",
      "(111)ZL ( 0.400520 - 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (0.0, 1.0), 2: (0.302826, 0.697174)}\n",
      "*********branch= 0T1F\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(001)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(101)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (1.0, 0.0), 2: (0.302826, 0.697174)}\n",
      "*********branch= 0F1T\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(010)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(110)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (1.0, 0.0), 1: (0.0, 1.0), 2: (0.302826, 0.697174)}\n",
      "*********branch= 0F1F\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(000)ZL ( 0.047936 + 0.270940j)\t prob=0.075706\n",
      "(100)ZL (-0.400520 + 0.117800j)\t prob=0.174294\n",
      "total probability of state vector (=one if no measurements)= 0.250000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (1.0, 0.0), 1: (1.0, 0.0), 2: (0.302826, 0.697174)}\n",
      "****************************ending PRINT output\n"
     ]
    }
   ],
   "source": [
    "init_st_vec = StateVec.get_ground_st_vec(num_qbits)\n",
    "sim = SEO_simulator(file_prefix, num_qbits, init_st_vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Initially, all qubits are in state |0>. Line 1 of the circuit rotates qubit 0 by an arbitrary one qubit rotation.\n",
    "Line 2 has a PRINT statement. If you look at the code for SEO_simulator.use_PRINT(),\n",
    "you will see that a PRINT statement in format \"ALL\" prints stuff to screen and also stores \n",
    "at sim.cached_sts[line_num] a copy of the current state.\n",
    "\n",
    "Next we convert the cached state at line_num=2 to\n",
    "a density matrix called den_mat1. Then we convert den_mat1 to a Pandas dataframe\n",
    "and display that dataframe as an HTML table. States are labeled in binary ZL (Zero bit last) convention."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style  type=\"text/css\" >\n",
       "</style><table id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00a\" ><thead>    <tr>        <th class=\"blank level0\" ></th>        <th class=\"col_heading level0 col0\" >000ZL</th>        <th class=\"col_heading level0 col1\" >001ZL</th>        <th class=\"col_heading level0 col2\" >010ZL</th>        <th class=\"col_heading level0 col3\" >011ZL</th>        <th class=\"col_heading level0 col4\" >100ZL</th>        <th class=\"col_heading level0 col5\" >101ZL</th>        <th class=\"col_heading level0 col6\" >110ZL</th>        <th class=\"col_heading level0 col7\" >111ZL</th>    </tr></thead><tbody>\n",
       "                <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row0\" class=\"row_heading level0 row0\" >000ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col0\" class=\"data row0 col0\" >(0.3028+0j)</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col1\" class=\"data row0 col1\" >(0.05087-0.4567j)</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col2\" class=\"data row0 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col3\" class=\"data row0 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col4\" class=\"data row0 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col5\" class=\"data row0 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col6\" class=\"data row0 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow0_col7\" class=\"data row0 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row1\" class=\"row_heading level0 row1\" >001ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col0\" class=\"data row1 col0\" >(0.05087+0.4567j)</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col1\" class=\"data row1 col1\" >(0.6972+0j)</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col2\" class=\"data row1 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col3\" class=\"data row1 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col4\" class=\"data row1 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col5\" class=\"data row1 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col6\" class=\"data row1 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow1_col7\" class=\"data row1 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row2\" class=\"row_heading level0 row2\" >010ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col0\" class=\"data row2 col0\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col1\" class=\"data row2 col1\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col2\" class=\"data row2 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col3\" class=\"data row2 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col4\" class=\"data row2 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col5\" class=\"data row2 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col6\" class=\"data row2 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow2_col7\" class=\"data row2 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row3\" class=\"row_heading level0 row3\" >011ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col0\" class=\"data row3 col0\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col1\" class=\"data row3 col1\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col2\" class=\"data row3 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col3\" class=\"data row3 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col4\" class=\"data row3 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col5\" class=\"data row3 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col6\" class=\"data row3 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow3_col7\" class=\"data row3 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row4\" class=\"row_heading level0 row4\" >100ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col0\" class=\"data row4 col0\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col1\" class=\"data row4 col1\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col2\" class=\"data row4 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col3\" class=\"data row4 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col4\" class=\"data row4 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col5\" class=\"data row4 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col6\" class=\"data row4 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow4_col7\" class=\"data row4 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row5\" class=\"row_heading level0 row5\" >101ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col0\" class=\"data row5 col0\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col1\" class=\"data row5 col1\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col2\" class=\"data row5 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col3\" class=\"data row5 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col4\" class=\"data row5 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col5\" class=\"data row5 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col6\" class=\"data row5 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow5_col7\" class=\"data row5 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row6\" class=\"row_heading level0 row6\" >110ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col0\" class=\"data row6 col0\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col1\" class=\"data row6 col1\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col2\" class=\"data row6 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col3\" class=\"data row6 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col4\" class=\"data row6 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col5\" class=\"data row6 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col6\" class=\"data row6 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow6_col7\" class=\"data row6 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00alevel0_row7\" class=\"row_heading level0 row7\" >111ZL</th>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col0\" class=\"data row7 col0\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col1\" class=\"data row7 col1\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col2\" class=\"data row7 col2\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col3\" class=\"data row7 col3\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col4\" class=\"data row7 col4\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col5\" class=\"data row7 col5\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col6\" class=\"data row7 col6\" >0j</td>\n",
       "                        <td id=\"T_4b797c4e_49ef_11ea_9593_015bba99c00arow7_col7\" class=\"data row7 col7\" >0j</td>\n",
       "            </tr>\n",
       "    </tbody></table>"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x7fe1ac16cf90>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# density  matrix cached at line number 2 of eng & pic files\n",
    "den_mat1 = StateVec.get_den_mat(num_qbits, sim.cached_sts[2])\n",
    "den_mat1_df = Plotter.get_den_mat_df(num_qbits, den_mat1)\n",
    "# pan.set_option('precision', 5)\n",
    "# print(\"\\nden_mat1=\\n\", den_mat1_df)\n",
    "den_mat1_df.style.format(\"{:.4}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we convert the final state (which is the current state of the simulator)\n",
    "to a density matrix called den_mat2. Then we convert that to a Pandas dataframe\n",
    "and display that dataframe as an HTML table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style  type=\"text/css\" >\n",
       "</style><table id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00a\" ><thead>    <tr>        <th class=\"blank level0\" ></th>        <th class=\"col_heading level0 col0\" >000ZL</th>        <th class=\"col_heading level0 col1\" >001ZL</th>        <th class=\"col_heading level0 col2\" >010ZL</th>        <th class=\"col_heading level0 col3\" >011ZL</th>        <th class=\"col_heading level0 col4\" >100ZL</th>        <th class=\"col_heading level0 col5\" >101ZL</th>        <th class=\"col_heading level0 col6\" >110ZL</th>        <th class=\"col_heading level0 col7\" >111ZL</th>    </tr></thead><tbody>\n",
       "                <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row0\" class=\"row_heading level0 row0\" >000ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col0\" class=\"data row0 col0\" >(0.0757+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col1\" class=\"data row0 col1\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col2\" class=\"data row0 col2\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col3\" class=\"data row0 col3\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col4\" class=\"data row0 col4\" >(0.0127-0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col5\" class=\"data row0 col5\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col6\" class=\"data row0 col6\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow0_col7\" class=\"data row0 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row1\" class=\"row_heading level0 row1\" >001ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col0\" class=\"data row1 col0\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col1\" class=\"data row1 col1\" >(0.0757+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col2\" class=\"data row1 col2\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col3\" class=\"data row1 col3\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col4\" class=\"data row1 col4\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col5\" class=\"data row1 col5\" >(0.0127-0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col6\" class=\"data row1 col6\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow1_col7\" class=\"data row1 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row2\" class=\"row_heading level0 row2\" >010ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col0\" class=\"data row2 col0\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col1\" class=\"data row2 col1\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col2\" class=\"data row2 col2\" >(0.0757+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col3\" class=\"data row2 col3\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col4\" class=\"data row2 col4\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col5\" class=\"data row2 col5\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col6\" class=\"data row2 col6\" >(0.0127-0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow2_col7\" class=\"data row2 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row3\" class=\"row_heading level0 row3\" >011ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col0\" class=\"data row3 col0\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col1\" class=\"data row3 col1\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col2\" class=\"data row3 col2\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col3\" class=\"data row3 col3\" >(0.0757+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col4\" class=\"data row3 col4\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col5\" class=\"data row3 col5\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col6\" class=\"data row3 col6\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow3_col7\" class=\"data row3 col7\" >(0.0127-0.114j)</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row4\" class=\"row_heading level0 row4\" >100ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col0\" class=\"data row4 col0\" >(0.0127+0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col1\" class=\"data row4 col1\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col2\" class=\"data row4 col2\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col3\" class=\"data row4 col3\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col4\" class=\"data row4 col4\" >(0.174+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col5\" class=\"data row4 col5\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col6\" class=\"data row4 col6\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow4_col7\" class=\"data row4 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row5\" class=\"row_heading level0 row5\" >101ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col0\" class=\"data row5 col0\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col1\" class=\"data row5 col1\" >(0.0127+0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col2\" class=\"data row5 col2\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col3\" class=\"data row5 col3\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col4\" class=\"data row5 col4\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col5\" class=\"data row5 col5\" >(0.174+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col6\" class=\"data row5 col6\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow5_col7\" class=\"data row5 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row6\" class=\"row_heading level0 row6\" >110ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col0\" class=\"data row6 col0\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col1\" class=\"data row6 col1\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col2\" class=\"data row6 col2\" >(0.0127+0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col3\" class=\"data row6 col3\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col4\" class=\"data row6 col4\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col5\" class=\"data row6 col5\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col6\" class=\"data row6 col6\" >(0.174+0j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow6_col7\" class=\"data row6 col7\" >0j</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00alevel0_row7\" class=\"row_heading level0 row7\" >111ZL</th>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col0\" class=\"data row7 col0\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col1\" class=\"data row7 col1\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col2\" class=\"data row7 col2\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col3\" class=\"data row7 col3\" >(0.0127+0.114j)</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col4\" class=\"data row7 col4\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col5\" class=\"data row7 col5\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col6\" class=\"data row7 col6\" >0j</td>\n",
       "                        <td id=\"T_4b7c138c_49ef_11ea_9593_015bba99c00arow7_col7\" class=\"data row7 col7\" >(0.174+0j)</td>\n",
       "            </tr>\n",
       "    </tbody></table>"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x7fe1ac16c350>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "den_mat2 = StateVec.get_den_mat(num_qbits, sim.cur_st_vec_dict)\n",
    "den_mat2_df = Plotter.get_den_mat_df(num_qbits, den_mat2)\n",
    "# print(\"\\nden_mat2=\\n\", den_mat2_df)\n",
    "den_mat2_df.style.format(\"{:.3}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we plot the entries of the square matrix den_mat2 as phasor arrows in a square grid (what is called a quiver plot). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD3CAYAAAA9memZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3deVxU9foH8M8MA8gmi8qmJoU4oCAIJKkIAiJqkZqZ5oLZ1VRcSH+4YG6gmGihP3G7LlFm/jQXSM3CXG+5W+rFDMWNRWAQBNlnmOH7+4PLXIltlgMDzPN+vXi9YGbOcx6Wh3Nm5pzP4THGGAghWoWv6QYIIS2PBp8QLUSDT4gWosEnRAvR4BOihWjwCdFCNPiEaCEa/BawdOlSbNq0SdNtECJHg09qEQqFSEtLk399+/ZtTJs2Df3798dbb72F+fPnIzc3V4MdEi7Q4JNGvXz5Eh988AHOnTuH8+fPw8jICBEREZpui6iJBr8Z3Lt3D2PGjEG/fv3w6aefQiwWy+87f/48Ro0aBU9PT0yYMAEpKSny+/z9/bF3714EBwfDw8OjzrL1uXbtGnx8fLB7924MGDAA3t7eOHPmDC5evIigoCD0798fO3fulD/+3//+N8aPHw9PT094e3sjKioKEokEADBp0iQAwKhRo9CvXz+cOnUKvr6+GDFiBIyNjWFgYIDJkyfjjz/+4PLHRTSBEU6JxWI2ZMgQFh8fzyQSCfvpp59Y7969WWxsLLt79y5766232O3bt5lUKmXHjh1jfn5+TCwWM8YY8/PzY2PHjmU5OTmsoKCADR8+nB04cKDR9V29epU5OTmxuLg4JpFI2KFDh5iXlxdbuHAhKy4uZg8ePGDOzs4sPT2dMcZYcnIyu3XrFqusrGQZGRls+PDhLD4+Xl6vV69e7OnTpw2uLz4+no0bN079HxTRKNric+zOnTuorKzE1KlToauri+HDh8PFxQUA8P3332P8+PFwdXWFjo4OxowZA11dXdy+fVu+/JQpU2BlZQUzMzP4+fnhr7/+anKdAoEAs2fPhq6uLkaOHImCggKEhITA2NgYDg4OcHBwwP379wEAzs7OcHNzg0AgQLdu3TB+/HjcuHFDoe8tJSUF27dvx+LFi1X4yZDWRKDpBtqb3NxcWFlZgcfjyW+ztbUFAGRlZSExMRH79++X31dZWVnrxbIuXbrIPzcwMFDohTQzMzPo6OgAADp06AAA6NSpk/x+fX19lJaWAgCePHmC9evX4+7duygvL4dMJkOfPn2aXEdaWhpmzJiBZcuWwdPTs8nHk9aNBp9jXbp0gUgkAmNMPvxZWVno3r07bGxsMGvWLMyePVtj/a1evRq9e/fGl19+CWNjY3z99ddISkpqdJlnz55h2rRpCA0NxejRo1uoU9KcaFefYzW70fv27YNUKsXp06eRnJwMABg3bhwOHjyIO3fugDGGsrIyXLhwASUlJS3WX2lpKYyMjGBkZIRHjx7h//7v/2rd37lzZ2RkZMi/FolEmDp1KiZOnIgPP/ywxfokzYsGn2N6enqIi4tDQkIC3nzzTZw6dQqBgYEAABcXF6xZswZRUVF48803MWzYMBw7dqxF+1uyZAlOnjwJd3d3rFixAiNHjqx1/9y5c7F06VJ4enri1KlTOHz4MDIyMrBt2zb069dP/kHaNh5jlMBDiLahLT4hWohe3GsDdu7ciX/+8591bvfw8MCePXs00BFp62hXnxAtRLv6hGghGnxCtBANPiFaiAafEC1Eg0+IFqLBJ0QL0eATooVo8AnRQjT4hGghGnxCtBANPiFaiAafEC1Eg/8fmzdvRnBwMHr37o24uLhGHzt9+vRaoRTOzs4IDg6u87jr169DKBSqdRUdiUSCiIgIuLu7Y9CgQYiPj6913/z58+Hv7w+hUIhr166pvB6iXei03P/o0aMHwsPDcfDgwSYf+/dTYadMmQIvL69at1VWViI6Ohqurq5q9RUXF4e0tDScP38eeXl5CAkJgb29PXx8fAAA7u7uCAkJwaeffqrWeoh2oS3+f4wZMwa+vr4wMjJSarnMzEzcvHkTo0aNqnV7fHw8Bg0ahDfeeKPW7VVVVdi1axeGDh0KLy8vhIWFobCwsMH6iYmJCA0NhampKezt7TFu3DgkJCQAqI75+uijj+Dp6Qk+n36VRHGt8q+lsLAQp0+fRnl5udLLzpw5E56envV+zJw5k/NeExMT4enpie7du8tve/bsGY4ePYo5c+bUefy+fftw5swZ7N+/H7/++itMTU0RFRVVb+2XL18iNzcXjo6O8tscHR3x8OFDzr8Pol2afVc/JycHBQUFSi3DGMO6deuQkZGBQYMGITAwEEOHDoWNjU2Ty9aXVNOcfvjhhzpx2WvXrkVYWFi9ew+HDh3CypUrYW1tDaA63NLPzw9SqRQCQe1fR1lZGQDAxMREfpuJiYk8I58QVTX74O/YsUOteKizZ8/i7Nmz4PF4mDhxIpYuXQoLCwsOO1TdzZs3kZeXh6CgIPlt586dQ2lpaZ302hpZWVmYM2dOrV1zPp+P/Px8bNu2DSdOnABQvedSE2ddUlICfX19+efKPh0h5O+affBnz56NCRMmKLUMYwyhoaHIyMiAt7c3AgMD0atXL3z55Zf48MMPYWZmhpiYGNjZ2dVZdvr06fj999/rrftqRl1MTAySkpLw7NkznDhxAr169VL6e0tMTERgYCAkEgk+/fRTpKeno7CwEMXFxRgwYAD4fD6Ki4uho6ODBw8eYMeOHbC2tsa6devg4eFRp15UVJR8tz80NBSnTp2CQCDA1KlTsXHjRjg5OSElJQU9e/ZUutcaW7duRVxcnMrfcw1/f3/o6enJ/yGFh4dj8ODBKtcTi8VYt24drly5An19fbi5uWHNmjUq1crMzKz1NKu4uBglJSW4fv26yv21O5q7bF/DCgoKWFJSEisrK5PfNmXKFJaYmMgYYywxMZFNmTJFrXXcuHGDZWVlMT8/P3b//n0mkUhYRUUFW7hwIYuNjWUVFRVMKpU2uHx5eTnz8PBgly9fZgUFBezq1auMMcaKi4vZypUr2YIFC1hubi4LCwtj0dHRrKCggDFWfdHJyZMns8zMTMYYY/n5+eyXX36pU7+oqIgxxtjGjRvZyJEjWXBwMHv48CEbNGgQu3jxovxxYrGYVVRUsMGDB7Nff/2VVVRUsKqqqnp7vnv3LvvHP/7BhgwZwu7fv6/aD+4/an5uXFmzZg2Ljo6W9/78+XPOaq9du5ZFRkZyVq89aJWD/3d5eXnMw8NDPohSqZR5eHiw/Px8tWvX/AEvWbKE9erVq9bH0aNHGWPV/yTc3NxqLXfixAk2ZMiQeofs559/ZlOnTmWMMbZkyRIWGxsrv08mk7GvvvqKDRs2jLm5ubGAgAD25ZdfNtifWCxmEydOZI6OjmzAgAHsq6++qtP/3/vOyMiot84HH3zA0tPTORlaLge/pKSEeXh4sJKSEk7qvUosFjMvLy929+5dzmu3ZW1i8JOTk9nIkSNr3TZixAhOfplcb7lkMhmbOnUq++abb9SutWzZMubr68t8fHzYgwcP1Kq1YcMGtn//fsYYN9+zn58fCw4OZu+88w5btWoVe/nypcq1/vrrLxYQEMDWr1/PxowZwyZPnsxu3LihVn81fvrpJ/buu+9yUqs9aZVv57Vla9asgaGhISZPnqx2rejoaFy4cAELFizAhg0bVK5z69YtJCcnY+LEiWr3VOO7777D8ePHcfToUTDGGnxLUhFSqRQZGRno3bs3jh07hvDwcMybN4+TawoePXoUY8eOVbtOe9MmBt/GxgYikQgymQwAIJPJkJubq9Dbey0pJiYGaWlp2Lx5M6cH1IwePRrXrl1T+m3RGjdu3MDjx48REBAAf39/5OTk4B//+Ad+++03lXuq+dnr6elh4sSJ+OOPP1SuZWtrC4FAgHfeeQcA4OrqCnNzczx58kTlmkD1BT9v3LhR7+HU2q5NDH6nTp3g5OSEkydPAgBOnjwJJyenVvO2HgBs2rQJd+/exbZt26Cnp6dWrdLSUmRnZ8u/PnfuHExNTWFmZqZSvU8++QS//fYbzp07h3PnzsHa2hp79+6Ft7e3SvXKyspQXFwMoPodmFOnTsHJyUmlWgBgYWEBLy8vXLp0CQDw5MkT5Ofno0ePHirXBICEhAT4+vrC3NxcrTrtUZu5ks6jR4+wdOlSFBUVoWPHjoiJialzOKwy1q5di9OnTyMvLw/m5uYwMzPDjz/+qFKt1NRUvPPOO7Czs0OHDh0AAN26dcO2bdtUqpeXl4fQ0FCUl5eDz+fD1NQUS5YsQZ8+fVSq93f+/v7YuXOnym/nZWRkYN68eZDJZKiqqoK9vT2WL18OS0tLlXvKyMjAsmXLUFhYCIFAgE8//RS+vr4q1wOAoKAgfPbZZ/LzGsh/tZnBJ4Rwp03s6hNCuEWDT4gWosEnRAvR4BOihdrU4BcVFSEuLg5FRUVUj+q1eL12RZOHDSorIyOjwWPRqR7Va+567Umb2uITQrhBg0+IFqLBJ0QLtanB19HRQdeuXaGjo0P1qF6L12tP6JBdQrRQi1xQo6CgFFVV3Px/6dTJGPn56p+nTfWonrL4fB7MzdtH0GmLDH5VFeNs8GvqcYnqUT1t06ae4xNCuEGDT4gWosEnRAvR4BOihWjwCdFCNPiEaCEafEK0EA0+IVqIBp8QjhQWFmLOnDlwc3ODn5+f/JLnAHDixAn4+fnBzc0NoaGhKCwsVGi5t99+G/369av14ezsDEdHRwDAtWvXVIoPb5Ej9wjRBlFRUdDV1cWlS5fw119/YebMmfIBXblyJXbt2oXevXtj5cqViIyMxKZNmxpdzsHBoc61HkpLS/H+++9jxIgRavVKg08IB8rKynD69GmcOHECRkZG8PT0hL+/P3744Qfw+Xz4+/vjzTffBACEhYVh5MiRKCkpAZ/Pb3C58PDwOutZvnw5bGxsMHfuXLX6pcEnhANPnz4Fn8/H66+/Lr/N0dERN27cAI/HQ79+/eS3v/baa9DV1ZUv09Byf7dv3z788ccfSEhIUPvajDT4hHCgrKwMJiYmtW4zMTFBaWkp+Hx+nfuMjY1RWloKHR2dBpd71e3bt7Fp0ybEx8dzcs1Ihf5tPHnyBOPHj0dQUBDGjx+Pp0+fqr1iQtoTQ0PDOpf1LikpgZGRkcr31Xjx4gXCwsKwcOFCuLm5cdKvQoO/atUqTJw4EUlJSZg4cSJWrlzJycoJaS/s7Owgk8lqbRRTUlLQs2dPODg4ICUlRX57RkYGKisrYWdn1+hyAFBVVYXw8HC4u7tjypQpnPXb5ODn5+fj3r178muXv/POO7h37x5evHjBWRPKKigowL59XyEtTb3rpxPCFUNDQwQGBmLLli0oKyvD77//jrNnz2LUqFEIDg7G+fPncfPmTZSVleF///d/ERgYCGNj40aXA4C4uDhkZ2dj7dq1ja5fLBbX+mgqWKvJ5/jZ2dmwsrKS55bp6OjA0tIS2dnZLX59+hcvXuDq1QsoKqrA99//H2JjN+C113rA19cPPj5+cHNzh66ursL10tPTYGBgx1l/z55lQlfXBgA3GW85OdnQ0akEoPj31JJevMiHVFoCgcCYk3qFhQUQi19CX9+Uk3rFxcUoK3sBQ8OW+TtdtWoVli1bhoEDB8LMzAyrV6+Gg4MDACAyMhLh4eEoLCzEgAED8Pnnnyu03I4dOyAQCODt7V1nfTVv9YlEIvTt27fWfadPn0aPHj0abrap4P3k5GQ2cuTIWreNGDGC3b17t3mS/htx5coVZmtrW+9Hnz592IoVK1hBQYHC9WbMmMF+/PFHzvpbuHAhO3jwIGf1VqxYwfbu3ctZva+//prFxsZyVm/79u0sOjqas3r79u1jS5cu5azesWPH2Ny5czmr1540GbaZn5+PoKAgXLt2DTo6OpDJZPDy8sLp06cV3uLn55dwEn9UVVUFc3MD5OQU4oMPRkFXVw8+PkPg6+uHvn3dVEpT7dLFBM+fF6vdW1uoFxOzFvfuJeObbw5xUg9o3d8v1/X4fB46deJm70bTmtzV79SpE5ycnHDy5EmMGjUKJ0+ehJOTU4vv5gMAn8+Hnp4eKisl2L59D7p3f63Fe2jLrKxscPbsaU23QVoBhd7HX716NZYuXYrt27ejY8eOiImJae6+GtWxoyk6duTmeaA2sbKywvPnz1FZKYGurp6m2yEapNDg29vb4/Dhw83dC2lm1tY2YIwhNzcXXbt203Q7RIPo7DwtYmlpBQAQiXI03AnRNBp8LcEYg6WlJXg8HnJysvH06WNNt0Q0iAZfSzx/nosFC+ZBT08PmzZtQELCUU23RDSIBl9LWFpaQV9fD2KxGM+fP0evXo6aboloEA2+FpkwYbL8c6FQqMFOiKbR4GsRT8/+cHR0hK6uLnr0eL3pBUi7RYOvRXg8HqZNm4Y33uip1DkNRDGqZu7t378f7733HpydnbF06dJaNadPn14nc8/FxQVCoRBZWVnIzMyEUCiEVCpVqlcK4tAy7733Hv7973uabqNdUjVzz9LSEqGhofj1118hFotr1dyzZ0+tr2UyGT766CPY2trC1tYWmZmZKvVKg69lDA0NMWPGLE230e6omrlnbGyMYcOGAQCSk5MhEokaXU9sbCwKCwuxa9cutfqlXX0tZGZmrukW2p2GMvcePnyI1NTUWi+mvpq5p4wzZ87g0KFDiIuLg4GBgVr90hafEA6omrmnqPT0dERERCA6Ohp2dnZq99vkFj8mJgb+/v4QCoV48OCB2iskpD1SN1evMWKxGPPnz8fYsWMRFBTESb9NDn5AQAC+++47dO3alZMVEtIeqZq5p4jIyEgYGBjUm7OvqiYH39PTEzY2NpytsDUqLS3B4cMHkZOTrelWSBulauYeAEilUojFYlRVVUEmk0EsFsvfnjty5AguXLiAzZs3QyBo+Jm5RCKplblXVVXVaL9t6jl+Tk42TE31OatXUlKCe/f+QGFhGb7//gCio1dDKHSSZ/j17t1HqQsX5OU9h6Ehd6+XvnjxAh06cFYOhYUF0NWVgatMQK6VlpaAxxMD4OZ3XF5eBpGoDHy+ISf1mqJq5t6OHTuwdetW+dfHjx/H3LlzMW/ePOzYsQMvX77E8OHD66xv9+7dsLa2BoBaF+wAgPj4eAwcOLDhZhXN6PLz82P3799vrggwhYwePZqdO3eOs3rJyckNZvi9/vrrbOHChez58+cK1wsNDWX79+/nrL/FixezHTt2cFZv7dq1bOPGjZzVS0xMZJs3b+as3t69e9mCBQs4q3fo0CE2ffp0zuq1J01m7tXw9/fHzp070atXL0UeXgtXmXsAtxlqUqkU+voMz58XY9asj5GfnwcfnyHw8fHDW28NgIGB8luK1pwZx3W9LVticfHiWRw9+mPTD1ZQa/5+tSpzrz0TCASwsDBBUZEYK1ZEoU8fZ7WvSaZNrK1tkJWVBcYYeDyeptshSmjyr3zt2rXw8fFBTk4Opk2bhrfffrsl+mpRRkbGcHHpS0OvJCsrK5SXl6O4uEjTrRAlNbnFX758OZYvX94SvZA2xsqq+t2enJwcCj9tY2gTR1RW84oyZfi1PTT4RGWmpmbo0KEDRKJsZGdnabodogQafKKSly8LsWTJQujp6eGrr3Zj9+4dmm6JKEGrX9UnqjM1NYNAIEBRURGKiorQqxdFebUltMUnKpswYZL8cwcHGvy2hAafqMzFxRWurq4AaPDbGhp8orKaDD8bG1t07NhR0+1oXEOZe7m5uZg1axa8vb0hFArrxGVJJBJERETA3d0dgwYNQnx8vPw+ytwjrdK7776LixcvabqNVqGhzD1zc3MMHjwYM2fOxIQJE+osFxcXh7S0NJw/fx55eXkICQmBvb09fHx8mi1zj7b4RC36+vqYOzdM021oXE3mXlhYWJ3Mvc6dO2PSpElwcXGpd9nExESEhobC1NQU9vb2GDduHBISEup9bE3m3urVq9XqlwafqK1Tp86abkHjGsvca8zLly+Rm5srT+NtbDkuM/do8AnhQGOZe00tV/PYxpbjOnOvyef4BQUFWLx4MdLT06Gnp4cePXogKioKFhYWaq+ckPZC1Vw9Q0ND+WP19fXrXU4jmXs8Hg/Tp09HUlISTpw4ge7du+OLL77gZOWEtBeNZe41xtTUFF26dKmVyff35TSSuWdmZgYvLy/5125ubsjKouOyGyMWi/Hjj8dRUFCg6VZIC2kscw+o/puQSCQA/puPV2P06NHyiK1Hjx7h8OHDGDNmDIDmy9xTOIEHAKqqqvDxxx/D398fISEhii7GWQJPQUEB3njDFgUF5WrXAqqPN3/tNSu8fClu+sEKEIvFEInSUFhYhi++WI/k5Dvo29dNnuFnb99TqcCKkpISWFuboaREufdoG1JWVoouXTqitFTGSb3y8jJYWBihvJybdCWA28QciUQCIyMdVFZykzHYVAJPYWEhli1bhsuXL8PMzAz/8z//g+DgYAD1X534/v378j5XrVqFpKQkdOjQATNmzMC0adMAVKdc5+TkQE9Pr87yNZl7AQEBde7jLHOPMcZWr17NZs+ezWQyWTOkgDUtODiYnT17lrN6kyZNYomJiZzVS0tLazDDr2vXriw0NJRlZ2crXG/RokVs+/btnPUXGRnJYmJiOKsXGxvLli9fzlm98+fPs61bt3JW7+DBg+zjjz/mrF57ovAWPyYmBvfv38fOnTvr/e/TGK62+JWVEtjYWCAvr6TpBytUrxI2Nuac1pNIivDiRSlWrFiK+/dTMGDAIPj4DMHgwb5Kv+0llUphadkRL16UcdIf1/VkMhk6dzbmbA/sq6924fvvD+Dnny9wUq+qqgoWFoYoLKzgpJ7WZe5t2rQJd+/exa5du5Qeei7p6upxmu2mq6vLeT1bWzsIBHn45JPZ8PDoL3+lVhUCgQA6OtxFYXNdT0dHp9HnncqysrKGSCRCZWUlJ5fx5vP5/6nDzeC3J03+1lJTU7Fz507Y2dnJDzfs1q0btm3b1uzNtVX6+voYOHCwpttoc6ysrMEYQ17ec9jY2Gq6nXatycF3cHCQvwhBSHOysvpvlBcNfvOiI/dIq2FpaQWAMvxaAg0+aTX09fXRqVMniEQ5yM/P03Q77RoNPmkVysvLsHr1ZxAIBDh69Hts3LhO0y21azT4pFWouVyZSCRCWtpTvP66vYY7at9o8EmrMWHCZPnnvXo5NvJIoi4afNJqODo6oX///gBAqb3NjAaftCrTpk2DsbExbG27arqVdo0Gn7QqI0aMgLe3T5u8+q6qYZunTp3ChAkT4OrqiilTptS6b+XKlXXCNl1dXSEUCnHjxg0A1ScApaWlKdUrhW2SVkVXVxcLFizWdBsqUTVs08zMDCEhIXj8+DGuXbtWp2ZUVFSt2xYtWgSRSAR3d3eVe6XBJ61OzRF8bUlN2OaJEyfqhG2Gh4dj0qRJDUZg15w+e/jw4SbXc+DAAVy9ehUJCQlqnXdBu/qEcEDVsE1lJCcnY+PGjdi0aRM6d1Yv4JQGnxAOqBq2qajCwkKEhYVh/vz58PT0VLueQrv6oaGhyMzMBJ/Ph6GhIVasWAEnJye1V05Ie6Fq2KYiGGNYtGgR+vTpI0/mUZdCgx8TEyP/b3bmzBksW7aswcB/wj2pVIp//es8+vcfAGPj9hEE0d68GrZZE3+tSNimIrZv34709HQcPXpU7Vo1FNrVf3UXpqSkRGNvtZSXlzcZIqiMiooKyGTc5M8B1Zl7yl7DrDFSqRSpqalIT0/DkSOHMGTIAMyc+TEOHNiHZ8+Uv3RSZaVEHvjIhcrKylqhkeqSSqWoqGiboRnqhG3KZDL5305VVRXEYjEqKysBAJcvX8aePXuwZcuWRv/p1/wuaj6a+rtWOHrrs88+w6VLl8AYw549e+Dg4KDIYgC4i94KCRmPRYvC4eLyptq1ACA0dDomT56IgQP9Oam3ePECBAQMQVDQKE7qFRYWYMiQAQ3eP2RIABYtikDXrt0UqhcbGwNz846YNm02J/3985/bIBaXYv58bt5+++67fXj6NBWffbaGk3p37tzCo0d/4b33JnJSr7nCNo8dO4aIiIha940ZMwbr169HSEgIbt68WW+SU2RkJN599916a69duxbjxo1rsFelUnaB6ut8/fjjj9i9e7cyi3GiqKgIRkZGnMVHFRcXw8DAgLP4qNLSUujq6nIWTyaVSuV56+vWrcOvv/6KN998E4GBgQgMDIS9vb1Se1/l5dXZeOpefqlGRUUFGGOc1avZ6nHxvBioTppdv349BcnUQ+nBB4C+ffvi4sWLMDc3V+jxXG3xAW7jl9tKvezsApw9expeXgNgZqbYz7yxeq39++Wq3vnzZ7FgwRz89ttNTl4baU9hm00+xy8tLUV2drb863PnzsHU1BRmZmbN2hj5L4FAgKCgkWoPvbaxsqpO9MnJyW7ikdqnyX3c8vJyhIWFoby8HHw+H6ampti5c2ebPJaaaBdraxsA1VFePXsq/pqUNmhy8Dt37ozvv/++JXohhFNmZubQ09OjDL960JF7pN3i8/mwsbFBTk42ioqKNN1Oq9LmBp8xhufPczXdBmnlKisl2LBhHXg8Hs6cScKqVcs03VKr0uYG//r16zh37oym2yCtnK6uHmQyKZ4+fYrHjx9RsMfftLnB/+qrr5CaSu/LkqbVzvCjKK9XtanBF4ly8NNPP+HBgxRNt0LagNdffwM+Pj4AAKGQwjtf1aYG//Dhg5DJZEhNTeX0mH3Sfk2bNg06Ojp44w31T5ZpT9rM4EskEhw9Wv22Ynl5GTIy0jXcEWkLAgIC4O3t0yJXed6/fz/ee+89ODs7Y+nSpbXuu3LlCoYPHy7P1Xv27Jn8PolEgoiICLi7u2PQoEGIj4+X3zd9+vQ6mXsuLi4QCoXIyspCZmYmhEKh0ieHtZnBv3nzOry8qk9Y6dHDjp7nE4Xo6Ohg0aKWeUXf0tISoaGhGDt2bK3bX7x4gblz5yIsLAzXr1+Hs7MzFixYIL8/Li4OaWlpOH/+PPbt24c9e/bgX//6FwBgz549uHXrlvzj5s2bcHNzw+jRo2Frq/qFRdvM4A8c6M61UMgAAA/qSURBVI2xYz8AAOzYsReurv003BFpK7p1694i6xk2bBiGDh1a53D2X375BQ4ODhgxYgT09fUxb948pKSk4NGjRwCqT3wLDQ2Fqakp7O3tMW7cuAbzLmJjY1FYWIjVq1er1WubCtvMzRWBz+fD0tKKszPqCGluqamptU6dNTQ0xGuvvYaHDx+ic+fOyM3NhaPjf198dHR0xNmzZ+vUOXPmDA4dOoQjR46ofUZkm9niA9UnW1haWtLQkzalvjw+Y2NjlJaWoqysDEDtsJv6svrS09MRERGB6OhoecKPOpQa/K1bt0IoFOLBgwdqr1gVIpEINjY2Glk3IaqqL4+vtLQURkZGMDSsvljoq/f/PatPLBZj/vz5GDt2LIKCgjjpSeHB//PPP3H79m21XlBQl0iUrdH1a6s//0ymw6TV4ODgIA9UAar3ANLT09GzZ0+YmpqiS5cute7/e1ZfZGQkDAwMEB4ezllPCu0zSyQSREVF4YsvvsDUqVM5W7myRCIRHBwGclaP62MBVMg0abIelzUZY8jOzkZ+vnKRz0+fPsWkSePQu7czfH394OvrB6HQSV6TS629XmOkUilkMhmqqqrkOXo6OjoIDAzEhg0bkJSUhCFDhmDbtm0QCoWwt6++FPjo0aOxY8cOODs7Iy8vD4cPH8a6desAAEeOHMGFCxeQkJDQ6FNciURSK2dPV1cXfH7D23WFEng2btwIW1tbTJo0Cf7+/ti5cyd69eql8A+EqwSeXbu2w8vLA66uXmrXAoA5c2Zg0qQPOcvcW7JkIfz9fTnL3IuKWoE+fRwxduwkTupJpVJ4ejpzUqtr127o08cF3brZcJa5d+DAPjx5wl3m3g8/HMPVq7/i8883cVKvqQSeuLg4bN26tdZtc+fOxbx583D58mVERUUhKysLrq6u+Pzzz9GtW3VWokQiwapVq5CUlIQOHTpgxowZ8hjtgIAA5OTk1Hscwu7du2FtbY2AgIA698XHx8uv0FOfJgf/1q1b2LRpE7755hvweDyVBr+1ev78OUxMTNChQwdO6uXn58PQ0JCzDLqCggLo6elxlkHHGMOVK1eUXu6vv/7CypUrYW5uDn9/fwwdOhRDhgwBj8eDTCbjLI2prKwMFRUVsLCw4KReeXk5SktL1b7qTHvU5ODv2rUL+/btk//HycnJQadOnfD555/D29tboZVQ5l7brnflyiV06NABffu61Qk6bQ39tVS99pS51+Rz/E8++QSffPKJ/Ov2tMUnihkwYJCmWyAca1Pv4xNCuKH0kTDnzp1rjj4IIS2ItviEaCEafFSfPUWINtH6wU9NTcXx43TlX6JdtP5sl/j4eOTm5mu6DUJalFYPfnFxMQ4fPkwJrETraPWu/vHjCSgrK8PTp084vW48Ia2d1g5+VVUVDh78DkD1MeyPHz/UcEekrVM1c+/UqVOYMGGC/L5XrVy5sk7mnqurK4RCIW7cuAEAEAqFSEtLU6pXrR3827f/gL199amP1tY2uH+fIruJelTN3DMzM0NISAhmzJhRp2ZUVFStzL1bt25h2LBh8PLygru7u8q9au1zfHd3TxgaGuHChbPYvHl7nYQUQpQ1bNgwAEBycjJEIpH89lcz9wBg3rx5eOutt/Do0SPY29vLz6I7fPhwk+s4cOAArl69ioSEhDrnTShDa7f4QHWwBwDY2tqia9duGu6GtFeNZe4pIzk5GRs3bsSmTZvUPuNQywdfBAMDA5iYdNR0K6QdayxzT1GFhYUICwvD/Pnz4enpqXZPCu3q+/v7Q09PD/r6+gCA8PBwDB48WO2Va1pOTnWUF4/H03QrpB1rLHNPEYwxLFq0CH369JEHdKhL4ef4W7ZsaXen4ubmUninJjx6VB0rbWrKTYBHa+fg4FArJ//VzD1FbN++Henp6Th69ChnPWnti3tA9Rb/jTfsNN1Gm1YdEa1chl9urggffDAKbm794ONTneFnZ/dGM3XYclTN3JPJZJBKpZBKpaiqqoJYLAafz4euri4uX76MPXv24ODBgzA2bjgEpLKyEmKxWP61QCBo9MU/hTL3/P39YWxsDMYYPDw8sHDhQnTsqPjzYq4SeGbMmIoFC8LQu7fqb2O8avv2LXB2doSPzzBO6i1fvgR+fj4ICHibk3qffx4FJ6deGD16Aif1tmyJhYVFR0yePJ2TegAwYEA/lJeXq13ntdd6wNW1H0xMDLF48UoOOgN+/PE4rl+/hMjIGE7qNVfm3rFjxxAREVFruTFjxmD9+vUICQnBzZs35U+zXxUZGYl333231guHNdauXYtx48Y12KtCg5+dnQ0bGxtIJBJER0ejtLQUX3zxRVOLce7p06ewtrbmLCOPa8+ePUPHjh05e2tQJBJBX1+fs0y7vLw88Hg8dOrUiZN6QPXVXZRNK87MzMSKFSugr6+PQYMGITAwEAEBATA2NkZZWRlnT79KSkrw8uVLdO1Kh2T/nUKD/6r79+9j9uzZSgVyUOYe1XvVlSuXUFFRgbfeGgADA8NW119DtCpzr6ysDDKZDCYmJmCM4dSpU3BycmqJ3kg7RRl+mtfk4Ofn52PevHnyFy3s7e2xatWqluiNENJMmhz87t27IzExsSV6IYS0EK0+co8QbUWD3wyKil5qugVCGkWDzzGRSCQ/z5+Q1ooGn2P79+/HvXt3Nd0GIY3S6kN2uVZZKcH+/fshEOhquhVCGkWDz6FffklCbm4ugOogTwr3IK0V7epz6ODB/fLPU1Pva7ATogkNZe5JJBLMnz8f/v7+EAqFuHbtWq3lGGPYuHEjvLy84OXlhQ0bNqDmgFrK3GvlUlL+gqFh9fnV5ubmePCABl/bNJS5BwDu7u7YsGEDunTpUue+Q4cO4cyZM/jhhx9w/PhxXLhwAQcPHgTQfJl7NPgcEQodsWJFFABgw4bN6N//LQ13RFrasGHDMHTo0DonVenp6eGjjz6Cp6cn+Py6I5eYmIiPP/4Y1tbWsLKywrRp02qdv/+qmsy92NhYtTL36Dk+R3g8HnJzqwMWbW27UoYfUVhqaiocHR3lXzs6OiI1NbXO42oy93bv3k2Ze61JTk51eKelpaWGOyFtSVlZWa2QDRMTE5SVleHVE2c1krknFouxbt06XLlyBfr6+nBzc8OaNWvUXnl7IxKJ0KVLF+jq6mm6FdKGGBoa1greLCkpgaGhoTwLUmOZexs3boS+vj6SkpLA4/GQl5fHycrbG5GoOryTtKxnzzJhYWFR59z+tsLBwQEpKSno27cvACAlJQUODg7y+zWSuVdaWorExERcvHhR/h9I3ecX7ZVIROGdmlBU9BLvvfc2PD294OMzBL6+frC2bvnfQ0OZewKBABKJRL7rXpOPp6enBx6Ph1GjRiE+Ph6+vr4Aqq/gPHnyZADQXOZeSkoK5s6di8DAQFy7dg1GRkYICwtT6nkGVwk88+fPwpw5syEUuqpdCwAiIsLx/vtj4OHBTTDE9u1b0K2bNd599wNO6sXGboBQaI+336779pAq/vnPbTA3N8EHH4RwUu/bb79GZWUZPv44lJN6ABAU5Cs/CEoZf/8z7tXLES4ufaGjAyxbFsVJb+pk7vn7+9e6Xh4AnD17Ft26dZO/j3/kyBEAwPvvv49FixaBx+NpLnPv7t27GDt2LL744gsEBwfjzp07mDVrFn755ZdG/wM1h3v37qFHjx4K55E35cGDB7CysoKpqSkn9biWlpYGAwMDzl4sfPbsGXg8HmdPR3JyciCVSuWhkVw4efIkKioqlFqmsLBQHg7Tr18/DB06FIGBgbCxscGLFy8UjrHWJk0O/osXLzB48GDcvXtXvqs/cuRIxMTEwMXFRaGVUOYe1WvOetevX0VW1jN4e/ugc+faB8hQ5l79mnyOb2FhAS8vL1y6dAne3t548uQJ8vPz0aNHj5boj5Am0cFSylPoVf3IyEgsW7YMMTExEAgE2LBhg1K5+oSQ1kWhwe/evTu+/fbb5u6FENJC6Mg9QrQQDX4bUFpa0vSDCFECDX4rV1JSgm+//VrTbZB2hga/lTty5Ahu3fpd022QdoZOy23FGGOIj49Hfn4+GGPy4ygIURdt8Vuxq1cv4+HDhygoKMDz58ofxkpIQ2jwW7FXM/woyqv1UzVz7+rVq5gyZQo8PDzg7+9f676dO3fWydxzc3ODUCiUX9rO398fly9fVqpXGvxW6tmzTBQUvAAAGBkZUXhnG6Bq5p6hoSHGjh2LxYsX17lv1qxZdTL3pk6dip49e2LYsGEq90rP8VspKytrbN26Gz4+/bFmzXqNnGZKlFMziMnJyRCJRPLbazL3ANSbude3b1/07dtXoa32xYsX8e233+Lw4cMwNFQ9f4AGv5USCATIzc0BUJ3h5+jYW8MdEU3LzMzE4sWLsWbNGtjb26tVi3b1W7GcnOrBt7S01nAnRNMkEgnCwsIQHByMt99+W+16TW7xMzMzMWfOHPnXxcXFKCkpwfXr19VeOWmcSJQDfX19mJuba7oVomFr166FQCDAkiVLOKnX5OB369YNP/zwg/zr6OhoyGQyTlZOGicS5cDGxobev29heXnP0bGjKfT0WkdoamJiIk6fPo2EhATo6nJzXUalnuNLJBKcOHECe/fu5WTlpHE1g09aVmFhAUaPHgEvrwHw8fHD4MFDYGFh0eRyqmbuVVVVobKyEpWVlWCMQSwWg8fjQU9PDw8ePEBkZCTi4uIa/Vv4e+ZezXob0mQCz6t+/vln7Nixo9YegCK4SuBZsmQhZsz4GD17OqtdCwAiI5dj9OhguLp6cVJv48bPMWiQFwYO9G/6wQrYvn0LDAx0MW3abE7qxcfvhrm5CUaPnsBJvYMHv4NMVoFJk/7BSb0TJxKRk5OBGTPmcVIPAD76aAIePXqs9HLFxUXyz3k8HlxcXPHhh5MQEjKxwWVUzdy7du0aQkJq5yD2798f3377LSIiIpCQkAADA4M665s5cyZmzZpVb+1Zs2ZhwYIFDfaq1ODPmDEDgwcPrtNkS/n999/h4ODAWQjInTt30L17d4X+myvizz//ROfOnWFlZcVJPa49fvwYfD4fdnZ2nNTLyMiAWCzmLNMuKysLRUVFta4qo66jR4+iqKio6Qe+QiwWIzo6GlVVVbCzs0NgYCCGDh0KLy8vzna1NU3hwReJRAgKCsL58+eVfrGJMveoXluq98cfN/Hvf9+Br68f7Oxel7/GolWZezUSEhLg6+tLrzCTds/d3RPu7upfpqo1U/h9/ISEhHoPRSSEtD0Kb/GTkpKasw9CSAuiI/cI0UI0+IRoIRp8QrQQDT4hWogGnxAtRINPiBaiwSdEC9HgE6KFaPAJ0UI0+IRoIRp8QrQQDT4hWogGnxAtRINPiBZqkQtq8PncpsRSPaqniXpc96VJSmXuEULaB9rVJ0QL0eATooVo8AnRQjT4hGghGnxCtBANPiFa6P8BsrSLnKAKBaEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "Plotter.plot_phasors(['den_mat2'], den_mat_df_list=[den_mat2_df])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we create a dataframe df by replacing each entry of den_mat2's dataframe by\n",
    "its magnitude. Then we display df as an HTML table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>000ZL</th>\n",
       "      <th>001ZL</th>\n",
       "      <th>010ZL</th>\n",
       "      <th>011ZL</th>\n",
       "      <th>100ZL</th>\n",
       "      <th>101ZL</th>\n",
       "      <th>110ZL</th>\n",
       "      <th>111ZL</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>000ZL</th>\n",
       "      <td>0.075706</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>001ZL</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.075706</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>010ZL</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.075706</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>011ZL</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.075706</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100ZL</th>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.174294</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>101ZL</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.174294</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>110ZL</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.174294</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>111ZL</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.114870</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.174294</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          000ZL     001ZL     010ZL     011ZL     100ZL     101ZL     110ZL  \\\n",
       "000ZL  0.075706  0.000000  0.000000  0.000000  0.114870  0.000000  0.000000   \n",
       "001ZL  0.000000  0.075706  0.000000  0.000000  0.000000  0.114870  0.000000   \n",
       "010ZL  0.000000  0.000000  0.075706  0.000000  0.000000  0.000000  0.114870   \n",
       "011ZL  0.000000  0.000000  0.000000  0.075706  0.000000  0.000000  0.000000   \n",
       "100ZL  0.114870  0.000000  0.000000  0.000000  0.174294  0.000000  0.000000   \n",
       "101ZL  0.000000  0.114870  0.000000  0.000000  0.000000  0.174294  0.000000   \n",
       "110ZL  0.000000  0.000000  0.114870  0.000000  0.000000  0.000000  0.174294   \n",
       "111ZL  0.000000  0.000000  0.000000  0.114870  0.000000  0.000000  0.000000   \n",
       "\n",
       "          111ZL  \n",
       "000ZL  0.000000  \n",
       "001ZL  0.000000  \n",
       "010ZL  0.000000  \n",
       "011ZL  0.114870  \n",
       "100ZL  0.000000  \n",
       "101ZL  0.000000  \n",
       "110ZL  0.000000  \n",
       "111ZL  0.174294  "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = den_mat2_df.apply(lambda x : np.sqrt((x*np.conj(x)).to_numpy().real))\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "df is a square dataframe of non-negative numbers so it begs to be plotted as a so called heatmap, using the wonderful package called seaborn."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEjCAYAAADQeG38AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3df1TUdb4/8OfMgGXZhKDioG5m6w9U3Cy0OiKlqLCIIhhLF0uzs3hqEQ6wltxsQVr2nuZsVFfdtqXdSE9QXhaSC8w6c2UXr3Ju3du5pRmaxhclkR/BSIiW2sf39w8vEzjMD4Yf82bm+bjnc47z+bzn8359PtudF5/3r49KCCFAREReTe3uAIiIyP2YDIiIiMmAiIiYDIiICEwGREQEJgMiIgKTgdfJysrC66+/7u4wvN6///u/45lnnhmy85WVleGf/umfhux85H2YDEhqs2fPxrlz5yyfP/vsM2zevBmLFy/Gww8/jLS0NLS1tbkxQtesXbsW77zzjuXzrddJNNKYDGhU+fbbb/GLX/wCf//73/GPf/wDd955J/75n//Z3WERjXpMBh6urq4OcXFxWLhwIdLT03H16tU+x//xj38gNjYWoaGheOKJJ3Dq1CnLseXLl+Mvf/kL1qxZgwcffLDf79/q448/Rnh4ON5++2088sgjCAsLw6FDh3D48GFERkZi8eLFeOuttyzljx8/jsTERISGhiIsLAwvv/wyrl27BgDYsGEDACA2NhYLFy6EwWDAo48+ip///OcYN24cxo4diyeffBL/+7//6/T9WL58Of785z9jzZo1uP/++/Hiiy+ivb0dv/zlL7Fw4UI8/fTT+Pbbby3l09LSsGTJEjz44IPYsGEDzpw5Yzl28eJFPPvss3jggQewfv16vP76632aambPno33338fq1atwqJFi5Cbm4ueCf+9m3X6u87+mn16Pz30rvvxxx9HY2Njn7L19fWWJ6jIyEgYDAan7xF5KUEe6+rVq+Kxxx4ThYWF4tq1a+Jvf/ubmDt3rnjttdeEEEKcOHFCPPzww+Kzzz4TP/zwgygrKxPLli0TV69eFUIIsWzZMrF+/XrR0tIiLl68KKKiokRxcbHdOj/66CMRHBwsdu/eLa5duyb2798vHnroIZGZmSkuXbokTp8+LebPny8aGxuFEEJ8/vnn4tNPPxXXr18XX3/9tYiKihKFhYWW882aNUucPXvWZn2FhYUiISHB6XuybNkykZCQIL755hvR0tIiHn74YbFu3TrxxRdfiKtXr4qnnnpK7N6921K+pKREXLp0SVy9elXk5eWJtWvXWo6lp6eL9PR0ceXKFXHmzBkRHh4unnjiiT6xb9myRXz77beiqalJPPTQQ+Lw4cNCCCFKS0utyva+zluP31omPT1dpKWlicuXL4svv/xShIWFWcpfvnxZhIeHi7/+9a/i+vXr4sSJE2Lx4sXi9OnTTt8n8j58MvBgx44dw/Xr17Fp0yb4+voiKioKISEhluP/9m//hsTERPzsZz+DRqNBXFwcfH198dlnn1nKPPXUUwgMDISfnx+WLVuGkydPOqzXx8cHzz33HHx9fREdHY2LFy9i48aNGDduHGbOnImZM2fiyy+/BADMnz8f999/P3x8fDB16lQkJibif/7nf5y6vlOnTuHNN9/ECy+8MKD78uSTT2LChAkIDAxEaGgoFixYgLlz52LMmDFYuXIl6urqLGUff/xxjBs3DmPGjEFqaipOnTqFS5cuQVEUmEwmpKamYuzYsfjpT3+KdevWWdWVnJwMrVaLoKAgPPTQQ32evFzVU3daWhruuOMOzJo1C3FxcZbjNTU1mDJlCtavXw8fHx/MmzcPkZGRMBqNg66bPJePuwOg4dPW1obAwECoVCrLvqCgIMu/L1y4gAMHDuC9996z7Lt+/XqfDtmJEyda/j127FinOmv9/Pyg0WgAALfffjsAICAgwHL8tttuw+XLlwEADQ0NeOWVV3DixAl89913UBQF8+bNc1jHuXPnkJycjBdffBGhoaEOy/c2YcKEPrH0/nz77bfjypUrAG7+6L7++us4ePAgzGYz1OqbfztdvHgR33//PX744QfodDrLd3v/u8et96/nugfDbDZb1d37f9empiYcP368z31RFAVr164ddN3kuZgMPNjEiRPR2toKIYQlIVy4cAHTpk0DcPPH69lnn8Vzzz3nthh37tyJuXPnIj8/H+PGjcO7777r8C/YpqYmbN68Gb/61a/6/Wt8qFRUVKC6uhqFhYWYOnUqLl26hEWLFkEIAX9/f/j4+KClpQX33nsvAKC5uXnI6h47diy+//57y+dvvvnG8u+eupubm3HfffdZ1a3T6bBo0SIUFhYOWTzk+dhM5MF6ml/2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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.close('all')\n",
    "ax = sea.heatmap(df, cmap=\"YlGnBu\")\n",
    "ax.set_title('den_mat2  magnitude')\n",
    "plt.yticks(rotation=0) \n",
    "plt.xticks(rotation=90)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The impurity of a density matrix $\\rho$ is defined as $abs({\\rm tr}(\\rho^2) - 1 )$. It equals zero iff $\\rho$\n",
    "is a pure state. Note that den_mat2 is not a pure state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "impurity of den_mat2= 0.75\n"
     ]
    }
   ],
   "source": [
    "print(\"impurity of den_mat2=\", StateVec.get_impurity(den_mat2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we calculate the trace over bits 0 and 1 of den_mat2. We call this partial\n",
    "density matrix tr01_den_mat2. We convert it to a dataframe, and display that dataframe as an HTML table.\n",
    "Note that the state at qubit 0 in den_mat1 has been successfully duplicated at qubit 2 \n",
    "with density matrix tr01_den_mat2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style  type=\"text/css\" >\n",
       "</style><table id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00a\" ><thead>    <tr>        <th class=\"blank level0\" ></th>        <th class=\"col_heading level0 col0\" >0</th>        <th class=\"col_heading level0 col1\" >1</th>    </tr></thead><tbody>\n",
       "                <tr>\n",
       "                        <th id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00alevel0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "                        <td id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00arow0_col0\" class=\"data row0 col0\" >(0.3028+0j)</td>\n",
       "                        <td id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00arow0_col1\" class=\"data row0 col1\" >(0.05087-0.4567j)</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00alevel0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "                        <td id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00arow1_col0\" class=\"data row1 col0\" >(0.05087+0.4567j)</td>\n",
       "                        <td id=\"T_4bcd2f2e_49ef_11ea_9593_015bba99c00arow1_col1\" class=\"data row1 col1\" >(0.6972+0j)</td>\n",
       "            </tr>\n",
       "    </tbody></table>"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x7fe17fc4be90>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tr01_den_mat2 = StateVec.get_partial_tr(num_qbits, den_mat2, {0, 1})\n",
    "tr01_den_mat2_df = Plotter.get_den_mat_df(1, tr01_den_mat2)\n",
    "# print(\"\\ntr01_den_mat2=\\n\", tr01_den_mat2_df)\n",
    "tr01_den_mat2_df.style.format(\"{:.4}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As expected, tr01_den_mat2 is a pure state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "impurity of tr01_den_mat2= 2.220446049250313e-16\n"
     ]
    }
   ],
   "source": [
    "print(\"impurity of tr01_den_mat2=\", StateVec.get_impurity(tr01_den_mat2))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {
    "height": "12px",
    "width": "252px"
   },
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
